package TanKWar;

import TanKWar.Elements.*;
import TanKWar.Tool.*;

import java.util.ArrayList;
import java.awt.*;
import java.awt.event.*;
import java.util.List;
import javax.swing.JOptionPane;

/**
 * 坦克大战的主类
 */

public class GameFrame extends Frame implements ActionListener {

    private static final long serialVersionUID = 5972735870004738773L;


    long startTime;//获取运行时间
    long usedTime = 0;
    /** 程序运行 processRun();*/

    /**
     * 获取当前的系统时间，与初始时间相减就是程序运行的毫秒数，除以1000就是秒数
     */

    public static int count = 7;
    
    public int judgehomewall = 0;//用来给道具传参,改变墙体
    public int judgemissile = 0;//在bullet类里面让子弹可以打穿铁墙
    
    public static final int Fram_width = 800; // 静态全局窗口大小
    public static final int Fram_length = 600;
    
    public static int RefreshTime = 40;//刷新界面的时间间隔（单位毫秒），可用来变化难度等级.
    
    public static boolean printable = true; // 记录暂停状态，此时线程不刷新界面
    MenuBar jmb = null;
    Menu jm1 = null, jm2 = null, jm3 = null, jm4 = null;
    MenuItem jmi1 = null, jmi2 = null, jmi3 = null, jmi4 = null, jmi5 = null, jmi6 = null, jmi7 = null, jmi8 = null,
            jmi9 = null;
    Image screenImage = null;


    public Tank homeTank = new Tank(300, 560, true, Direction.STOP, this);// 实例化坦克
    public Blood blood = new Blood(); // 实例化血包
    public Missile missile = new Missile();//实例化三个道具,导弹，变化家里的墙，加强tank
  	public Change_hw ch_hw = new Change_hw();
  	public Strengthen strengthen = new Strengthen();
    public Home home = new Home(373, 545, this);// 实例化home



    // 以下集合变量在构造方法中进行了初始化
    public List<River> theRiver = new ArrayList<River>();
    public List<Tank> tanks = new ArrayList<Tank>();
    public List<BombTank> bombTanks = new ArrayList<BombTank>();
    public List<Bullets> bullets = new ArrayList<Bullets>();
    public List<Tree> trees = new ArrayList<Tree>();
    public List<BrickWall> homeWall = new ArrayList<BrickWall>(); // 实例化对象容器
    public List<BrickWall> otherWall = new ArrayList<BrickWall>();
    public List<MetalWall> metalWall = new ArrayList<MetalWall>();
    public List<MetalWall> hwhomeWall = new ArrayList<MetalWall>();//家里的铁墙
    
    
    // 这是一个重写的方法,将由repaint()方法自动调用
    public void update(Graphics g) {

        screenImage = this.createImage(Fram_width, Fram_length);

        Graphics gps = screenImage.getGraphics();
        Color c = gps.getColor();
        
        gps.setColor(new Color(88, 87, 86));
        gps.fillRect(0, 0, Fram_width, Fram_length);
        gps.setColor(c);

        framPaint(gps);

        g.drawImage(screenImage, 0, 0, null);
    }

    //
    public void framPaint(Graphics g) {

       
        Color c = g.getColor();
        g.setColor(Color.green); // 设置字体显示属性
        //blood.setLive(false);
        // 如果玩家赢了（条件是敌方坦克全灭、大本营健在、玩家坦克仍有血量）
        if (tanks.size() == 0 && home.isLive() && homeTank.isLive()) {
            Font f = g.getFont();
            g.setFont(new Font("TimesRoman", Font.BOLD, 60));
            
            this.tanks.clear();// 作清理页面工作
            this.metalWall.clear();
            this.otherWall.clear();
            this.bombTanks.clear();
            this.theRiver.clear();
            this.trees.clear();
            this.bullets.clear();
            
    		//this.homeTank.setLive(false);
    		this.blood.setjudgeblood(true);
    		this.ch_hw.setjudgehw(true);//让其不在刷新，也要让其消失
    		this.strengthen.setjudgestreng(true);
    		this.missile.setjudgemiss(true);
            this.blood.setLive(false);
			this.ch_hw.setLive(false);
			this.strengthen.setLive(false);
			this.missile.setLive(false);
            g.drawString("你赢了！ ", 310, 300);
            g.setFont(f);
            printable = false;
        }

        /*if (homeTank.isLive() == false) {//坦克没血了之后
            Font f = g.getFont();
            g.setFont(new Font("TimesRoman", Font.BOLD, 40));
            tanks.clear();
            bullets.clear();
            g.setFont(f);
            
        }*/

        //g.setColor(c);

        for (int i = 0; i < theRiver.size(); i++) { // 画出河流
            River r = theRiver.get(i);
            r.draw(g);
        }

        for (int i = 0; i < theRiver.size(); i++) {
            River r = theRiver.get(i);
            homeTank.collideRiver(r);//坦克撞到河流
            //r.draw(g);
        }

        home.draw(g); // 画出home
        homeTank.draw(g); // 画出自己家的坦克
        homeTank.eat(blood);// 加血--生命值
        homeTank.eat(missile);//导弹，可打破铁墙
      	homeTank.eat(ch_hw);//改变家里的墙为铁墙      		      	
      	homeTank.eat(strengthen);//加快tank移速和攻速


        // 画出每一辆敌方坦克
        for (int i = 0; i < tanks.size(); i++) {
            Tank t = tanks.get(i); // 获得键值对的键
            for (int j = 0; j < homeWall.size(); j++) {
                BrickWall cw = homeWall.get(j);
                t.collideWithWall(cw); // 每一个坦克撞到家里的墙时
                cw.draw(g);
            }
            for (int j = 0; j < otherWall.size(); j++) { // 每一个坦克撞到家以外的墙
                BrickWall cw = otherWall.get(j);
                t.collideWithWall(cw);
                cw.draw(g);
            }
            for (int j = 0; j < metalWall.size(); j++) { // 每一个坦克撞到金属墙
                MetalWall mw = metalWall.get(j);
                t.collideWithWall(mw);
                mw.draw(g);
            }
            
            if(judgehomewall == 1) {
            	for (int j = 0; j < hwhomeWall.size(); j++) { // 每一个坦克撞到金属墙
                    MetalWall hw = hwhomeWall.get(j);
                    t.collideWithWall(hw);
                    hw.draw(g);
                }
            }
            
            for (int j = 0; j < theRiver.size(); j++) {
                River r = theRiver.get(j); // 每一个坦克撞到河流时
                t.collideRiver(r);
                //r.draw(g);
                // t.draw(g);
            }

            t.collideWithTanks(tanks); // 撞到自己的人
            t.collideHome(home);

            t.draw(g);
        }     

        

        for (int i = 0; i < otherWall.size(); i++) { // 画出otherWall
            BrickWall cw = otherWall.get(i);
            cw.draw(g);
        }

        for (int i = 0; i < metalWall.size(); i++) { // 画出metalWall
            MetalWall mw = metalWall.get(i);
            mw.draw(g);
        }
        
        if(judgehomewall == 1) {
        	for (int i = 0; i < hwhomeWall.size(); i++) { // 画出hwhomeWall
        		MetalWall hw = hwhomeWall.get(i);
                hw.draw(g);
            }
        }
		
		blood.draw(g);// 画出加血包
        missile.draw(g);//画出三个道具
      	ch_hw.draw(g);
      	strengthen.draw(g);
		
        homeTank.collideWithTanks(tanks);//自己的坦克撞到了这些东西
        homeTank.collideHome(home);

        for (int i = 0; i < metalWall.size(); i++) {// 撞到金属墙
            MetalWall w = metalWall.get(i);
            homeTank.collideWithWall(w);
            w.draw(g);
        }

        if(judgehomewall == 1) {
        	for (int i = 0; i < hwhomeWall.size(); i++) { // 撞到hwhomeWall
        		MetalWall hw = hwhomeWall.get(i);
        		homeTank.collideWithWall(hw);
                hw.draw(g);
            }
        }
        
        for (int i = 0; i < otherWall.size(); i++) {//其他的普通墙
            BrickWall cw = otherWall.get(i);
            homeTank.collideWithWall(cw);
            cw.draw(g);
        }

        for (int i = 0; i < homeWall.size(); i++) { // 家里的坦克撞到自己家
            BrickWall w = homeWall.get(i);
            homeTank.collideWithWall(w);
            w.draw(g);
        }

        for (int i = 0; i < bullets.size(); i++) { // 对每一个子弹
            Bullets m = bullets.get(i);//的到指定位置中节点的数据
            m.hitTanks(tanks); // 每一个子弹打到坦克上
            m.hitTank(homeTank); // 每一个子弹打到自己家的坦克上时
            m.hitHome(); // 每一个子弹打到家里时

            for (int j = 0; j < metalWall.size(); j++) { // 每一个子弹打到金属墙上
                MetalWall mw = metalWall.get(j);
                m.hitWall(mw,this.judgemissile);
            }

            if(judgehomewall == 1) {
            	for (int j = 0; j < hwhomeWall.size(); j++) { // 撞到hwhomeWall
            		MetalWall hw = hwhomeWall.get(j);
            		m.hitWall(hw,this.judgemissile);
                }
            }
            
            for (int j = 0; j < otherWall.size(); j++) {// 每一个子弹打到其他普通墙上
                BrickWall w = otherWall.get(j);
                m.hitWall(w);
            }

            for (int j = 0; j < homeWall.size(); j++) {// 每一个子弹打到家的墙上
                BrickWall cw = homeWall.get(j);
                m.hitWall(cw);
            }
            m.draw(g);
            // 画出效果图
        }

     
        for (int i = 0; i < bombTanks.size(); i++) { // 画出爆炸效果
            BombTank bt = bombTanks.get(i);
            bt.draw(g);
        }
        for (int i = 0; i < trees.size(); i++) { // 画出trees
            Tree tr = trees.get(i);
            tr.draw(g);
        }
        //让坦克不会挡住提示信息
        //g.setColor(c);
        
        Font f1 = g.getFont();//Font是字体
        g.setFont(new Font("TimesRoman", Font.BOLD, 15));
        g.drawString("区域内还有敌方坦克: ", 40, 90);

        g.setFont(new Font("TimesRoman", Font.ITALIC, 20));
        g.drawString("" + tanks.size(), 212, 90);

        g.setFont(new Font("TimesRoman", Font.BOLD, 15));
        g.drawString("剩余生命值: ", 330, 90);

        g.setFont(new Font("TimesRoman", Font.ITALIC, 20));
        g.drawString("" + homeTank.getLife(), 430,90);

        g.setFont(new Font("TimesRoman", Font.BOLD, 15));
        g.drawString("运行时间: ", 560, 90);
        
        long endTime = System.currentTimeMillis();//获取运行时间
        if((endTime - startTime) < 150)
        usedTime += (endTime - startTime);       
        
        startTime = System.currentTimeMillis();
        g.setFont(new Font("TimesRoman", Font.ITALIC, 20));
        g.drawString("" + usedTime/1000, 650, 90);
        
        g.setFont(f1);

    }
    
    //试一下道具转换墙体，在铁墙中添加。用铁墙画出
    public void change_wall() {
    	for (int i = 0; i < 10; i++) { 
    	if(judgehomewall == 1){    		    		
    		if (i < 4)
    			hwhomeWall.add(new MetalWall(350, 580 - 21 * i, this));//左边那一列
            else if (i < 7)
            	hwhomeWall.add(new MetalWall(372 + 22 * (i - 4), 517, this));//中间那一排
            else
            	hwhomeWall.add(new MetalWall(416, 538 + (i - 7) * 21, this));
    	}
    	}
    }
    
    
    

    
    public GameFrame() {
        // printable = false;
        // 创建菜单及菜单选项
        startTime = System.currentTimeMillis();//获取运行时间
        jmb = new MenuBar();
        jm1 = new Menu("游戏");
        jm2 = new Menu("暂停/继续");
        jm3 = new Menu("帮助");
        jm4 = new Menu("游戏级别");
        jm1.setFont(new Font("TimesRoman", Font.BOLD, 15));// 设置菜单显示的字体
        jm2.setFont(new Font("TimesRoman", Font.BOLD, 15));// 设置菜单显示的字体
        jm3.setFont(new Font("TimesRoman", Font.BOLD, 15));// 设置菜单显示的字体
        jm4.setFont(new Font("TimesRoman", Font.BOLD, 15));// 设置菜单显示的字体

        jmi1 = new MenuItem("开始新游戏");
        jmi2 = new MenuItem("退出");
        jmi3 = new MenuItem("暂停");
        jmi4 = new MenuItem("继续");
        jmi5 = new MenuItem("游戏说明");
        jmi6 = new MenuItem("级别1");
        jmi7 = new MenuItem("级别2");
        jmi8 = new MenuItem("级别3");
        jmi9 = new MenuItem("级别4");
        jmi1.setFont(new Font("TimesRoman", Font.BOLD, 15));// 设置菜单显示的字体
        jmi2.setFont(new Font("TimesRoman", Font.BOLD, 15));
        jmi3.setFont(new Font("TimesRoman", Font.BOLD, 15));
        jmi4.setFont(new Font("TimesRoman", Font.BOLD, 15));
        jmi5.setFont(new Font("TimesRoman", Font.BOLD, 15));

        jm1.add(jmi1);
        jm1.add(jmi2);
        jm2.add(jmi3);
        jm2.add(jmi4);
        jm3.add(jmi5);
        jm4.add(jmi6);
        jm4.add(jmi7);
        jm4.add(jmi8);
        jm4.add(jmi9);

        jmb.add(jm1);
        jmb.add(jm2);

        jmb.add(jm4);
        jmb.add(jm3);

        jmi1.addActionListener(this);
        jmi1.setActionCommand("NewGame");
        jmi2.addActionListener(this);
        jmi2.setActionCommand("Exit");
        jmi3.addActionListener(this);
        jmi3.setActionCommand("Stop");
        jmi4.addActionListener(this);
        jmi4.setActionCommand("Continue");
        jmi5.addActionListener(this);
        jmi5.setActionCommand("help");
        jmi6.addActionListener(this);
        jmi6.setActionCommand("level1");
        jmi7.addActionListener(this);
        jmi7.setActionCommand("level2");
        jmi8.addActionListener(this);
        jmi8.setActionCommand("level3");
        jmi9.addActionListener(this);
        jmi9.setActionCommand("level4");

        this.setMenuBar(jmb);// 菜单Bar放到JFrame上
        this.setVisible(true);
        //布局这一部分可以拆出来
        for (int i = 0; i < 10; i++) { // 家的格局
        	if(judgehomewall == 0) {
            if (i < 4)
                homeWall.add(new BrickWall(350, 580 - 21 * i, this));//左边那一列
            else if (i < 7)
                homeWall.add(new BrickWall(372 + 22 * (i - 4), 517, this));//中间那一排
            else
                homeWall.add(new BrickWall(416, 538 + (i - 7) * 21, this));//右边那一列
        	}
            else if(judgehomewall == 1){
        		
        		if (i < 4)
        			metalWall.add(new MetalWall(350, 580 - 21 * i, this));//左边那一列
                else if (i < 7)
                	metalWall.add(new MetalWall(372 + 22 * (i - 4), 517, this));//中间那一排
                else
                	metalWall.add(new MetalWall(416, 538 + (i - 7) * 21, this));//右边那一列
        	}
        	
        }

        for (int i = 0; i < 32; i++) { // 砖墙
            if (i < 16) {
                otherWall.add(new BrickWall(220 + 20 * i, 300, this)); // 砖墙布局
                otherWall.add(new BrickWall(500 + 20 * i, 180, this));
                otherWall.add(new BrickWall(200, 400 + 20 * i, this));
                otherWall.add(new BrickWall(500, 400 + 20 * i, this));
            } else if (i < 32) {
                otherWall.add(new BrickWall(220 + 20 * (i - 16), 320, this));
                otherWall.add(new BrickWall(500 + 20 * (i - 16), 220, this));
                otherWall.add(new BrickWall(220, 400 + 20 * (i - 16), this));
                otherWall.add(new BrickWall(520, 400 + 20 * (i - 16), this));
            }
        }

        for (int i = 0; i < 20; i++) { // 金属墙布局
            if (i < 10) {
                metalWall.add(new MetalWall(140 + 30 * i, 150, this));
                metalWall.add(new MetalWall(600, 400 + 20 * (i), this));
            } else if (i < 20)
                metalWall.add(new MetalWall(140 + 30 * (i - 10), 180, this));
            else
                metalWall.add(new MetalWall(500 + 30 * (i - 10), 160, this));
        }


        for (int i = 0; i < 4; i++) { // 树的布局
            if (i < 4) {
                trees.add(new Tree(0 + 30 * i, 360, this));
                trees.add(new Tree(220 + 30 * i, 360, this));
                trees.add(new Tree(440 + 30 * i, 360, this));
                trees.add(new Tree(660 + 30 * i, 360, this));
            }
        }

        theRiver.add(new River(84, 100, this));

        for (int i = 0; i < count; i++) { // 初始化count辆坦克
            if (i < 9) // 设置坦克出现的位置
                tanks.add(new Tank(150 + 70 * i, 40, false, Direction.D, this));
            else if (i < 15)
                tanks.add(new Tank(700, 140 + 50 * (i - 6), false, Direction.D, this));
            else
                tanks.add(new Tank(10, 50 * (i - 12), false, Direction.D, this));
        }

        this.setSize(Fram_width, Fram_length); // 设置界面大小
        // this.setLocation(280, 50); // 设置界面出现的位置
        setLocationRelativeTo(null);// 让窗体居中
        this.setTitle("坦克大战(重新开始：R键  开火：F键)                 ");

        this.addWindowListener(new WindowAdapter() { // 窗口关闭的监听(右上角那个×)
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });

        this.addWindowStateListener(new WindowStateListener() {//解决窗口绿屏问题

            public void windowStateChanged(WindowEvent state) {
                if (state.getNewState() == 0) {
                    printable = true;
                    new Thread(new PaintThread()).start();

                    new Thread() {
                        public void run() {
                            try {
                                Thread.sleep(41);
                                printable = false;
                            } catch (InterruptedException e) {
                            }
                        }
                    }.start();
                }
            }
        });

        this.setResizable(false);
        this.setBackground(Color.GREEN);
        this.setVisible(true);

        this.addKeyListener(new KeyMonitor());// 键盘监听
        new Thread(new PaintThread()).start(); // 线程启动
    }

    public static void main(String[] args) {
        new GameFrame(); // 实例化
    }


    //多线程的一个方法
    private class PaintThread implements Runnable {
        public void run() {
            // TODO Auto-generated method stub
            while (printable) {
                repaint();
                //System.gc();//回收内存
                try {
                    Thread.sleep(RefreshTime);//刷新界面时间间隔（单位毫秒）
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private class KeyMonitor extends KeyAdapter {//继承适配器类

        public void keyReleased(KeyEvent e) { // 监听键盘释放
            homeTank.keyReleased(e);
        }

        public void keyPressed(KeyEvent e) { // 监听键盘按下
            homeTank.keyPressed(e);
        }
    }

    public void actionPerformed(ActionEvent e) {//ActionListener里面的方法，就是最外面的控制面板的菜单栏的选项

        if (e.getActionCommand().equals("NewGame")) {
            printable = false;
            Object[] options = {"确定", "取消"};
            int response = JOptionPane.showOptionDialog(this, "您确认要开始新游戏！", "", JOptionPane.YES_OPTION,
                    JOptionPane.QUESTION_MESSAGE, null, options, options[0]);
            if (response == 0) {//菜单栏开始新游戏

                printable = true;
                this.dispose();//用于关闭窗口，并释放内存
                new GameFrame();
            } else {
                printable = true;
                new Thread(new PaintThread()).start(); // 线程启动
            }

        } else if (e.getActionCommand().endsWith("Stop")) {// 暂停，endsWith测试字符串是否以指定的后缀结束。
            printable = false;
            // try {
            // Thread.sleep(10000);
            //
            // } catch (InterruptedException e1) {
            // // TODO Auto-generated catch block
            // e1.printStackTrace();
            // }
        } else if (e.getActionCommand().equals("Continue")) {// 继续
            if (!printable) {
                printable = true;
                new Thread(new PaintThread()).start(); // 线程启动
            }
            // System.out.println("继续");
        } else if (e.getActionCommand().equals("Exit")) {// 退出
            printable = false;
            Object[] options = {"确定", "取消"};
            int response = JOptionPane.showOptionDialog(this, "您确认要退出吗", "", JOptionPane.YES_OPTION,
                    JOptionPane.QUESTION_MESSAGE, null, options, options[0]);
            if (response == 0) {
                System.out.println("退出");
                System.exit(0);
            } else {
                printable = true;
                new Thread(new PaintThread()).start(); // 线程启动
            }
        } else if (e.getActionCommand().equals("help")) {
            printable = false;
            JOptionPane.showMessageDialog(null, "用→ ← ↑ ↓控制方向，F键盘发射，R重新开始！", "提示！", JOptionPane.INFORMATION_MESSAGE);
            this.setVisible(true);
            printable = true;
            new Thread(new PaintThread()).start(); // 线程启动
        } /*else if (e.getActionCommand().equals("level1")) {
            Tank.count = 12;
            Tank.speedX = 6;
            Tank.speedY = 6;
            Bullets.speedX = 10;
            Bullets.speedY = 10;
            this.dispose();
            new GameFrame();
        } else if (e.getActionCommand().equals("level2")) {
            Tank.count = 12;
            Tank.speedX = 10;
            Tank.speedY = 10;
            Bullets.speedX = 12;
            Bullets.speedY = 12;
            this.dispose();
            new GameFrame();

        } else if (e.getActionCommand().equals("level3")) {
            Tank.count = 20;
            Tank.speedX = 14;
            Tank.speedY = 14;
            Bullets.speedX = 16;
            Bullets.speedY = 16;
            this.dispose();
            new GameFrame();
        } else if (e.getActionCommand().equals("level4")) {
            Tank.count = 25;
            Tank.speedX = 16;
            Tank.speedY = 16;
            Bullets.speedX = 18;
            Bullets.speedY = 18;
            this.dispose();
            new GameFrame();
        }*/
    }
}
